import {
  ITEM_RARITY,
  ITEM_TYPE,
  SKILL_MASTERY_LEVEL,
  type CultivationSkillItemConfig,
  type EquipmentItemConfig,
  type EquipSlot,
  type EquipType,
  type ItemRarity,
  type MaterialItemConfig,
  type SkillMasteryLevel,
} from '../../data/item/type';
import {
  ATTRIBUTE_TYPE_ORDER,
  type AttributeType,
} from '../../model/attributes/type';
import type { AuthorInfo } from '../../types';
import { CONDITION_TYPE, type Condition } from '../condition-checker/type';

interface CultivationSkillQuickOpts {
  id: string;
  name: string;
  rarity: ItemRarity;
  maxLevel?: number;
  studyConditions?: Condition[];
  baseCultivationSpeed?: number;
  basePrice?: number;
  canSell?: boolean;
  author?: AuthorInfo;
  expFn?: (lv: number) => number; // 想换曲线可继续传
  speedFn?: (lv: number) => number;
  breakAt?: (lv: number) => undefined | Condition[];
}

interface EquipmentQuickOpts {
  id: string;
  name: string;
  equipType: EquipType;
  equipSlot: EquipSlot;
  /** [攻击,生命,防御,速度] */
  baseAttr: [number, number, number, number];
  basePrice?: number;
  canSell?: boolean;
}

interface MaterialQuickOpts {
  id: string;
  name: string;
  basePrice?: number;
  canSell?: boolean;
  rarity?: ItemRarity;
}

/** 多项式缓升曲线 */
function polyExp(lv: number): number {
  /** a·lv³ + b·lv² + c·lv   （a=4，b=60，c=30） */
  return 4 * lv * lv * lv + 60 * lv * lv + 30 * lv;
}

function masteryOf(lv: number): SkillMasteryLevel {
  if (lv <= 5) return SKILL_MASTERY_LEVEL.BEGINNER;
  if (lv <= 10) return SKILL_MASTERY_LEVEL.MINOR_ACHIEVEMENT;
  if (lv <= 15) return SKILL_MASTERY_LEVEL.MAJOR_ACHIEVEMENT;
  if (lv <= 20) return SKILL_MASTERY_LEVEL.PERFECTION;
  return SKILL_MASTERY_LEVEL.SUBLIME;
}

function defaultBreakAt(lv: number): Condition[] {
  switch (lv) {
    case 5:
      return [
        {
          type: CONDITION_TYPE.REALM,
          realm: 5,
        },
      ];
    case 10:
      return [
        {
          type: CONDITION_TYPE.REALM,
          realm: 11,
        },
      ];
    case 15:
      return [
        {
          type: CONDITION_TYPE.REALM,
          realm: 15,
        },
      ];
    case 20:
      return [
        {
          type: CONDITION_TYPE.REALM,
          realm: 19,
        },
      ];
    default:
      return [];
  }
}

function defaultSpeed(lv: number): number {
  const stage = Math.floor((lv - 1) / 5);
  return 10 * Math.pow(2, stage);
}

export class ItemFactory {
  /** 创建功法配置 */
  static createCultivationSkillItemConfig(
    opts: CultivationSkillQuickOpts
  ): CultivationSkillItemConfig {
    const {
      id,
      name,
      rarity,
      maxLevel = 25,
      baseCultivationSpeed = 10,
      basePrice = 1,
      canSell = true,
      studyConditions = [],
      author,
      expFn = polyExp,
      speedFn = defaultSpeed,
      breakAt = defaultBreakAt,
    } = opts;

    const levels = Array.from({ length: maxLevel }, (_, i) => {
      const level = i + 1;
      return {
        level,
        masteryLevel: masteryOf(level),
        requiredExp: expFn(level),
        cultivationSpeedBonus: speedFn(level),
        breakthroughCondition: breakAt(level),
      };
    });

    return {
      id: id,
      name: name,
      author,
      rarity: rarity,
      baseCultivationSpeed,
      levels: levels,
      maxLevel,
      basePrice,
      canSell,
      studyConditions,
      type: ITEM_TYPE.CULTIVATION_SKILL,
      maxStack: 999,
    };
  }

  /** 创建装备配置 */
  static createEquipmentItemConfig(
    opts: EquipmentQuickOpts
  ): EquipmentItemConfig {
    const {
      id,
      name,
      equipType,
      equipSlot,
      baseAttr = [0, 0, 0, 0],
      basePrice = 1,
      canSell = true,
    } = opts;

    const newBaseAttr = baseAttr.map((v, idx) => ({
      prop: ATTRIBUTE_TYPE_ORDER[idx] as AttributeType,
      base: v,
    }));

    return {
      id,
      name,
      type: ITEM_TYPE.EQUIPMENT,
      equipType,
      equipSlot,
      basePrice,
      canSell,
      maxStack: 1,
      baseAttr: newBaseAttr,
      equipConditions: [], // 默认空，需要外部再补
    };
  }

  /** 创建材料配置 */
  static createMaterialItemConfig(opts: MaterialQuickOpts): MaterialItemConfig {
    const {
      id,
      name,
      rarity = ITEM_RARITY.COMMON,
      basePrice = 1,
      canSell = true,
    } = opts;
    return {
      id,
      name,
      type: ITEM_TYPE.MATERIAL,
      rarity,
      basePrice,
      canSell,
      maxStack: 999,
    };
  }
}
